public class PLLearnLayerPattern extends PLLearnLayer {
	PLPattern[] mPatterns;
	protected PLMNDist mDists;
	
	public PLLearnLayerPattern() {
		super();
	}
	
	public PLLearnLayerPattern(String name) {	
		super(name);
		Init();
	}
	
	public boolean Init() {
		// makes sense to test and add all available patterns
		mPatterns = PLPattern.GetAllPatterns();

		// init distributions for the patterns 

		mDists = new PLMNDist();		
		mDists.Init(PLShape.GetNumShapes(), NumPatterns());

		return true;
	}

	public void Learn(PLShape query,PLShape response) {
		if (!query.IsValid() || !response.IsValid()) 
			return;

		// get the shape of the query and the equivalent distribution
		PLDist dist = mDists.GetDistributionAt(query.GetShapeId().getId());

		PLOutShape dummy = new PLOutShape();
		for (int i =0; i < NumPatterns(); ++i) {			
			float confidence = mPatterns[i].ValidateResponse( query, response, dummy);
			float factor = PLLearnUtils.GetMultiplicationFactor(confidence);
			dist.MultiplyValueAt(i, factor);
		}
	}

	public void Finished() {								
		SaveDataToFile();
	}

	public int NumPatterns() {return mPatterns.length;}

	// PRIVATE MEMBERS
	private boolean SaveDataToFile() {
		PLFileUtils.MakeFullDirPath(GetName());
		String filename = PLFileUtils.GetPatternFile(GetName());
		
		String[] names = new String[NumPatterns()];
		for (int i =0; i < NumPatterns(); ++i) {
			names[i] = mPatterns[i].GetName();
 		}

		PLRecordKeyValue<PLMNDist, String[]> record = new PLRecordKeyValue<PLMNDist, String[]>();		
		record.Set(mDists, names); 	
						
		// get the key value file name
		PLFileKeyValue<PLMNDist, String[]> file = new PLFileKeyValue<PLMNDist, String[]>(filename);
		file.WriteRecord(record);
		
		// just one record to write, we are all done
		file.FinishedWriting();
												
		// all done 	
		return true;
	}	
}
